package com.avic.modules.backup4MySQL;

import com.avic.modules.backup4MySQL.vo.FileVo;
import com.avic.utils.DateUtils;
import com.smattme.MysqlExportService;
import com.smattme.MysqlImportService;
import lombok.extern.slf4j.Slf4j;

import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.sql.SQLException;
import java.text.SimpleDateFormat;
import java.time.LocalDateTime;
import java.time.ZoneOffset;
import java.time.format.DateTimeFormatter;
import java.util.*;

@Slf4j
public class MySQLBackup {

    private static final String SEP = File.separator;
    public static String SQL_EXTERNAL_DIR = System.getProperty("user.home") + SEP + ".ehs" + SEP + "file" + SEP + "tmp" + SEP + "external" + SEP;
    public static String SQL_TMP_DIR = "sql" + SEP;
    public static String SQL_EXTENSION = ".sql";
    public static int MAGIC_SEVEN = 7;
    public static String DATE_DETAIL_FORMAT = "yy:MM:dd HH:mm:ss";


    private String sqlPath;
    private Properties properties;

    public static void main(String[] args) throws SQLException, IOException, ClassNotFoundException {
        String jdbcURL = "jdbc:mysql://192.168.110.254:13307/Ehs?serverTimezone=Asia/Shanghai&characterEncoding=utf8&useSSL=false&zeroDateTimeBehavior=convertToNull&allowPublicKeyRetrieval=true";
        String dbName = "ehs";
        String userName = "root";
        String passWord = "root";
        String driver = "com.mysql.cj.jdbc.Driver";
        MySQLBackup backup = new MySQLBackup();
        backup.init(dbName, userName, passWord, jdbcURL, driver);
        backup.exportSQL();
        System.out.println(backup.getSqlPath());
        seven11("/Users/ayetony.miao/.avic/file/tmp/external/sql/");
    }

    /**
     * 7 天备份 seven eleven
     */
    public static void seven11(String sqlDir) {
        File sqlFile = new File(sqlDir);
        if (sqlFile.isDirectory()) {
            File[] files = sqlFile.listFiles();
            for (File file : files) {
                if (!file.getAbsolutePath().endsWith(".sql")) {
                    file.delete();
                    files = sqlFile.listFiles();
                }
            }
            if (files.length > MAGIC_SEVEN) {
                Arrays.sort(files, (f1, f2) -> {
                    long deltaDiff = f1.lastModified() - f2.lastModified();
                    if (deltaDiff > 0) {
                        return 1;
                    } else if (deltaDiff == 0) {
                        return 0;
                    } else {
                        return -1;
                    }
                });
                for (int i = 0; i < files.length - MAGIC_SEVEN; i++) {
                    files[i].delete();
                }
            }
        } else {
            throw new RuntimeException("【 The file is not folder or dir ,check with ops】");
        }

    }

    public String getSqlPath() {
        return sqlPath;
    }

    public void setSqlPath(String sqlPath) {
        this.sqlPath = sqlPath;
    }

    /**
     * 初始化
     *
     * @param dbName      数据库名
     * @param userName    用户名
     * @param password    密码
     * @param jdbcConnUrl jdbc 连接地址
     */
    public void init(String dbName, String userName, String password, String jdbcConnUrl, String driverClassName) {
        properties = new Properties();
        properties.setProperty(MysqlExportService.DB_NAME, dbName);
        properties.setProperty(MysqlExportService.DB_USERNAME, userName);
        properties.setProperty(MysqlExportService.DB_PASSWORD, password);
        properties.setProperty(MysqlExportService.ADD_IF_NOT_EXISTS, "true");
        properties.setProperty(MysqlExportService.PRESERVE_GENERATED_ZIP, "false");
        properties.setProperty(MysqlExportService.PRESERVE_GENERATED_SQL_FILE, "true");
        properties.setProperty(MysqlExportService.JDBC_DRIVER_NAME, driverClassName);
        properties.setProperty(MysqlExportService.JDBC_CONNECTION_STRING, jdbcConnUrl);
        properties.setProperty(MysqlExportService.TEMP_DIR, new File(SQL_EXTERNAL_DIR).getPath());
    }

    /**
     * 此方法用来导出
     */
    public void exportSQL() throws SQLException, IOException, ClassNotFoundException {
        String sqlFileName = DateUtils.dateTimeNow();
        properties.setProperty(MysqlExportService.SQL_FILE_NAME, sqlFileName);
        MysqlExportService mysqlExportService = new MysqlExportService(properties);
        mysqlExportService.export();
        String generatedSql = mysqlExportService.getGeneratedSql();
        log.info("generated SQL: \n" + generatedSql);
        File sqlFile = new File(SQL_EXTERNAL_DIR + SQL_TMP_DIR + sqlFileName + SQL_EXTENSION);
        this.setSqlPath(sqlFile.getAbsolutePath());
        seven11(SQL_EXTERNAL_DIR + SQL_TMP_DIR);
    }


    public static List<FileVo> getSqlPathMap() {
        File sqlFileDirectory = new File(SQL_EXTERNAL_DIR + SQL_TMP_DIR);
        if (sqlFileDirectory.isDirectory()) {
            HashMap<Long, String> sqlPathMap = new HashMap<>();
            File[] files = sqlFileDirectory.listFiles();
            SimpleDateFormat simpleDateFormat = new SimpleDateFormat(DATE_DETAIL_FORMAT);
            List<FileVo> fileVoList = new ArrayList<>();
            for (int i = files.length - 1; i >= 0; i--) {
                if(!files[i].isDirectory() && files[i].getName().endsWith(SQL_EXTENSION)) {
                    String mt = String.valueOf(files[i].lastModified());
                    FileVo fileVo = new FileVo();
                    fileVo.setMtime(Long.parseLong(mt.substring(0, mt.length() - 3)));
                    fileVo.setPathName(files[i].getAbsolutePath());
                    fileVoList.add(fileVo);
                }else{
                    System.out.println(files[i].getName());
                }
            }
            fileVoList.sort((o1, o2) -> o2.getMtime().compareTo(o1.getMtime()));
            return fileVoList;
        }
        return null;
    }

    private static String formatEpoch(long epoch){
        LocalDateTime dateTime = LocalDateTime.ofEpochSecond(epoch / 1000L, 0, ZoneOffset.ofHours(8));
        return dateTime.format(DateTimeFormatter.ofPattern(DATE_DETAIL_FORMAT));
    }

    /**
     * @param sqlFile sql 文件导入还原
     */
    public boolean importSQLViaUser(File sqlFile) throws SQLException, ClassNotFoundException, IOException {
        String sql = new String(Files.readAllBytes(sqlFile.toPath()));
        MysqlImportService importService = MysqlImportService.builder()
                .setJdbcDriver("com.mysql.cj.jdbc.Driver")
                .setJdbcConnString(properties.getProperty(MysqlExportService.JDBC_CONNECTION_STRING))
                .setDatabase(properties.getProperty(MysqlExportService.DB_NAME))
                .setSqlString(sql)
                .setUsername(properties.getProperty(MysqlExportService.DB_USERNAME))
                .setPassword(properties.getProperty(MysqlExportService.DB_PASSWORD))
                .setDropExisting(true)
                .setDeleteExisting(true);
        return importService.importDatabase();
    }

}
